Skip to content

Add remastered OGV cutscene playback with MIDI music sync#587

Open
elliotttate wants to merge 5 commits intoluciusDXL:masterfrom
elliotttate:remaster-cutscenes
Open

Add remastered OGV cutscene playback with MIDI music sync#587
elliotttate wants to merge 5 commits intoluciusDXL:masterfrom
elliotttate:remaster-cutscenes

Conversation

@elliotttate
Copy link
Copy Markdown

Summary

  • Adds support for playing the remastered OGV (Ogg Theora) video cutscenes from the Dark Forces Remaster, with the original iMUSE MIDI music synchronized to match
  • Pre-scans the original FILM cutscene chain to extract CUST actor cue points and their timestamps, then scales them to OGV duration so MIDI transitions fire at the correct visual moments for all cutscenes
  • Includes SRT subtitle support with the existing accessibility/caption system, OGV audio mixing alongside MIDI, and a user-facing toggle in the settings UI
  • Builds are gated behind ENABLE_OGV_CUTSCENES (CMake) / preprocessor define so it has zero impact when disabled

Details

  • New files: ogvPlayer.cpp/h (Theora/Vorbis decoding + OpenGL YUV rendering), remasterCutscenes.cpp/h (OGV path resolution from remaster install), srtParser.cpp/h (subtitle loading)
  • Modified: cutscene.cpp (OGV playback path + FILM-driven cue scheduling), audioSystem (PCM mixing for OGV audio), renderBackend (fullscreen quad for video frames), settings (remaster cutscene toggle), frontEndUi (settings checkbox)
  • CMakeLists.txt adds optional theoradec, ogg, vorbis dependencies behind the option flag
  • vcxproj updated for Windows builds with bundled ogg/theora/vorbis libs

Test plan

  • Play intro cutscene (scene 10) — music should start and transition at the same moments as the original LFD cutscene
  • Skip cutscene with ESC/Space/Enter — music should stop, no leftover state
  • Play with remaster cutscenes disabled in settings — original LFD path should be unaffected
  • Build without ENABLE_OGV_CUTSCENES — should compile cleanly with no OGV code included
  • Build on Linux with CMake + the theora/ogg/vorbis packages installed

Play Nightdive remaster's Ogg Theora video cutscenes when available,
falling back to original LFD/FILM cutscenes otherwise. Uses libtheora
for video decoding, libvorbis for audio, and a YUV->RGB GPU shader for
rendering. Includes SRT subtitle support, auto-detection of remaster
install paths, and a settings toggle.

Gated behind ENABLE_OGV_CUTSCENES compile flag.
Replace the hardcoded cue timer with a pre-scan approach that extracts
music cue points from the original FILM cutscene chain. Each FILM's CUST
actor is loaded and ticked to capture its cue value and timestamp, then
all times are scaled to match the OGV video duration. This ensures MIDI
music transitions fire at the correct visual moments for all cutscenes,
not just the intro.
Comment thread TheForceEngine/TFE_DarkForces/Landru/cutscene.cpp Outdated
The remaster's actual timing mechanism is a per-scene DCSS text script
that fires seq/cue/musicvol directives against the video's clock. Our
previous approach of pre-scanning LFD FILMs and scaling to OGV duration
was approximate and fragile. This switches to a real DCSS parser that
matches the remaster's format byte-for-byte (including its parse
quirks), and dispatches cues against the video's intrinsic clock for
sub-frame accuracy.

Code:
- New dcssParser.{h,cpp}: tolerant SRT-like parser, sorted-on-load,
  '#'/'//' comments. All 13 stock .dcss files validated.
- cutscene.cpp: dropped FILM pre-scan. OGV path now reads DCSS and
  dispatches via getVideoTime() for hitch-proof sync. musicvol now
  scales 100 = base (matches CUTSCENE.LST convention and the LFD
  path); previous /127 made every cutscene ~20% quiet.
- remasterCutscenes: key lookups on scene->scene (matches remaster),
  added getDcssPath() with auto-detection by walking up from movies/.
  Locale-aware OGV and SRT lookup (logo_de.ogv, arcfly_de.srt, ...).
- ogvPlayer: new getVideoTime() returning the intrinsic video clock.

Docs in Documentation/markdown/remaster-cutscenes/:
README, architecture, dcss-format, modding-guide, video-conversion
(MP4 -> OGV pipeline tested end-to-end with a verified ffmpeg
one-liner), troubleshooting.

Measured timing drift: 0-33ms (<=1 frame at 30fps) over 1:53 of
playback, bounded, no accumulation.
Master's b557d7c renamed FileUtil::directoryExits -> directoryExists
(fixing the typo). Update the remaster cutscene path resolution to
match. No behavior change.
@elliotttate
Copy link
Copy Markdown
Author

Update: DCSS-driven cutscenes + hardening + docs

Significant follow-up work pushed to this branch:

What changed

  • Replaced the FILM pre-scan entirely with a real DCSS parser. DCSS is the remaster's per-scene text script (lives in DarkEX.kpf at cutscene_scripts/<scene>.dcss) — I pulled the actual files out, matched the remaster's parser byte-for-byte (including the parse quirks like 00:00:58:827 and 00:1:50,487), and verified all 13 stock scripts parse identically. This also resolves @ifeldshteyn's comment about the missing getDuration() — that call went away with the rest of the scaling math.
  • Dispatch against the video's intrinsic clock, not wall-clock, so music cues stay locked to the visible frame when the game hitches. Measured drift over full logo.ogv: 0–33 ms, bounded, no accumulation.
  • Fixed musicvol: scale — was dividing by 127 (made every cutscene ~20% quiet), now divides by 100 to match the CUTSCENE.LST convention and the LFD path at cutscene_player.cpp:151.
  • Parser hardening: sorted-on-load (defensive against hand-edited DCSS), # / // comment support, bounded string parsing, tolerant of locale typos.
  • Locale-aware file lookup: logo_de.ogv, arcfly_de.srt etc. (matches remaster's convention).
  • Merged master — picks up @luciusDXL's FileUtil::directoryExists rename from Fixing FileUtil exists check for windows. updating directoryExists ca… #590.

New documentation

Six markdown files under TheForceEngine/Documentation/markdown/remaster-cutscenes/:

  • README.md — overview + quick starts
  • architecture.md — pipeline diagram, path resolution, dispatch loop rationale, stock cutscene.lst reference
  • dcss-format.md — complete format spec with stock annotated examples
  • modding-guide.md — end-to-end walkthrough
  • video-conversion.mdverified MP4 → OGV ffmpeg command lines (tested end-to-end with a 30s clip + hand-written DCSS, 3/3 cues fired with 0ms video drift)
  • troubleshooting.md

Verification

  • Debug + Release builds clean (Windows v143, SDK 10.0.26100.0).
  • Full logo.ogv (1:53, 5 DCSS cues) played end-to-end under the DCSS_TIMING_TRACE instrumentation; see commit message for the drift table.
  • Parser regression suite: 5 edge cases (stock files, unsorted, comments, truncated, empty buffer) — all pass.

Tracing flag DCSS_TIMING_TRACE in cutscene.cpp ships disabled; flip to 1 for per-cue drift logs when authoring new DCSS files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants